﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Infrastructure.Helper
{
    /// <summary>
    /// 提供用于从 JSON 字符串中提取数据的帮助方法。支持通过路径访问 JSON 数据中的值。
    /// </summary>
    public class JsonHelper
    {
        /// <summary>
        /// 存储反序列化后的 JSON 数据。
        /// </summary>
        private IDictionary<string, object> jsonData { get; set; }

        /// <summary>
        /// 构造函数，接受一个 JSON 字符串并将其反序列化为字典对象。
        /// </summary>
        /// <param name="json">待反序列化的 JSON 字符串</param>
        public JsonHelper(string json)
        {
            // 使用 JsonConvert 反序列化 JSON 字符串为字典对象
            jsonData = JsonConvert.DeserializeObject<IDictionary<string, object>>(json);
        }

        /// <summary>
        /// 根据路径获取字符串值。
        /// </summary>
        /// <param name="path">访问路径，以点分隔的字段名</param>
        /// <returns>对应路径的字符串值，如果路径不存在则返回 null</returns>
        public string GetString(string path)
        {
            return (string)GetObject(path);
        }

        /// <summary>
        /// 根据路径获取整数值。
        /// </summary>
        /// <param name="path">访问路径，以点分隔的字段名</param>
        /// <returns>对应路径的整数值，如果路径不存在或无法转换为整数则返回 null</returns>
        public int? GetInt(string path)
        {
            int? result = null;
            object @object = GetObject(path);
            if (@object == null)
            {
                return result;
            }
            // 如果结果不是字符串，则直接转换为整数
            return (!(@object is string)) ? new int?((int)@object) : new int?(int.Parse((string)@object));
        }

        /// <summary>
        /// 根据路径获取对应的对象值。
        /// </summary>
        /// <param name="path">访问路径，以点分隔的字段名</param>
        /// <returns>对应路径的值，如果路径不存在则返回 null</returns>
        public object GetObject(string path)
        {
            object result = null;
            // 开始时从顶级字典进行查找
            IDictionary<string, object> dictionary = jsonData;
            string[] array = path.Split('.');
            int num = array.Count();
            try
            {
                // 遍历路径中的每个部分，逐层深入
                for (int i = 0; i < num; i++)
                {
                    string key = array[i];
                    if (i == num - 1)
                    {
                        // 如果是最后一层，返回对应的值
                        result = dictionary[key];
                    }
                    else
                    {
                        // 否则继续深入到下一层字典
                        dictionary = (IDictionary<string, object>)dictionary[key];
                    }
                }
            }
            catch
            {
                // 如果发生任何异常（如键不存在或类型不匹配），直接跳过并返回 null
            }
            return result;
        }
    }

}
